home *** CD-ROM | disk | FTP | other *** search
/ 3D GFX / 3D GFX.iso / amiutils / i_l / irit5 / triv_lib / triv_ref.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-31  |  10.2 KB  |  287 lines

  1. /******************************************************************************
  2. * SBsp_Ref.c - Refinements for Tri-Variate Bsplines.                  *
  3. *******************************************************************************
  4. * Written by Gershon Elber, Sep. 94.                          *
  5. ******************************************************************************/
  6.  
  7. #include <string.h>
  8. #include "triv_loc.h"
  9.  
  10. /*****************************************************************************
  11. * DESCRIPTION:                                                               M
  12. * Given a trivariate, refines it at the given n knots as defined by the      M
  13. * vector t.                                     M
  14. *   If Replace is TRUE, the values replace the current knot vector.         M
  15. *   Returns pointer to refined TV (Note a Bezier trivariate will be          M
  16. * converted into a Bspline trivariate).                         M
  17. *                                                                            *
  18. * PARAMETERS:                                                                M
  19. *   TV:       Trivariate to refine according to t in direction Dir.          M
  20. *   Dir:      Direction of refinement. Either U or V or W.                   M
  21. *   Replace:  If TRUE t is a knot vector exaclt in the length of the knot    M
  22. *             vector in direction Dir in TV and t simply replaces than knot  M
  23. *          vector. If FALSE, the knot vector in direction Dir in TV is    M
  24. *          refined by adding all the knots in t.                 M
  25. *   t:        Knot vector to refine/replace the knot vector of TV in         M
  26. *          direction Dir.                             M
  27. *   n:        Length of vector t.                                            M
  28. *                                                                            *
  29. * RETURN VALUE:                                                              M
  30. *   TrivTVStruct *:    The refined trivariate. Always a Bspline trivariate.  M
  31. *                                                                            *
  32. * KEYWORDS:                                                                  M
  33. *   TrivTVRefineAtParams, trivariates                                        M
  34. *****************************************************************************/
  35. TrivTVStruct *TrivTVRefineAtParams(TrivTVStruct *TV,
  36.                    TrivTVDirType Dir,
  37.                    CagdBType Replace,
  38.                    CagdRType *t,
  39.                    int n)
  40. {
  41.     TrivTVStruct *BspTV, *TTV;
  42.  
  43.     switch (TV -> GType) {
  44.     case TRIV_TVBEZIER_TYPE:
  45.             BspTV = TrivCnvrtBezier2BsplineTV(TV);
  46.         TTV = TrivBspTVKnotInsertNDiff(BspTV, Dir, Replace, t, n);
  47.         TrivTVFree(BspTV);
  48.         return TTV;
  49.     case TRIV_TVBSPLINE_TYPE:
  50.         return TrivBspTVKnotInsertNDiff(TV, Dir, Replace, t, n);
  51.     default:
  52.         TRIV_FATAL_ERROR(TRIV_ERR_UNDEF_GEOM);
  53.         return NULL;
  54.     }
  55. }
  56.  
  57. /*****************************************************************************
  58. * DESCRIPTION:                                                               M
  59. * Given a Bspline trivariate, inserts n knots with different values as       M
  60. * defined by t.                                     M
  61. *   If, however, Replace is TRUE, the knot are simply replacing the current  M
  62. * knot vector in the prescribed direction.                     M
  63. *                                                                            *
  64. * PARAMETERS:                                                                M
  65. *   TV:       Trivariate to refine according to t in direction Dir.          M
  66. *   Replace:  If TRUE t is a knot vector exaclt in the length of the knot    M
  67. *             vector in direction Dir in TV and t simply replaces than knot  M
  68. *          vector. If FALSE, the knot vector in direction Dir in TV is    M
  69. *          refined by adding all the knots in t.                 M
  70. *   t:        Knot vector to refine/replace the knot vector of TV in         M
  71. *          direction Dir.                             M
  72. *   n:        Length of vector t.                                            M
  73. *                                                                            *
  74. * RETURN VALUE:                                                              M
  75. *   TrivTVStruct *:    The refined trivariate.  A Bspline trivariate.        M
  76. *                                                                            *
  77. * KEYWORDS:                                                                  M
  78. *   TrivBspTVKnotInsertNDiff, trivariates                                    M
  79. *****************************************************************************/
  80. TrivTVStruct *TrivBspTVKnotInsertNDiff(TrivTVStruct *TV,
  81.                        TrivTVDirType Dir,
  82.                        int Replace,
  83.                        CagdRType *t,
  84.                        int n)
  85. {
  86.     CagdBType
  87.     IsNotRational = !TRIV_IS_RATIONAL_TV(TV);
  88.     int i, ODim,
  89.     ULength = TV -> ULength,
  90.     VLength = TV -> VLength,
  91.     WLength = TV -> WLength,
  92.     UOrder = TV -> UOrder,
  93.     VOrder = TV -> VOrder,
  94.     WOrder = TV -> WOrder,
  95.     MaxCoord = CAGD_NUM_OF_PT_COORD(TV -> PType);
  96.     TrivTVStruct
  97.     *RefTV = NULL;
  98.  
  99.     if (Replace) {
  100.     for (i = 1; i < n; i++)
  101.         if (t[i] < t[i - 1])
  102.         TRIV_FATAL_ERROR(TRIV_ERR_KNOT_NOT_ORDERED);
  103.  
  104.         switch (Dir) {
  105.         case TRIV_CONST_U_DIR:
  106.         if (TV -> UOrder + TV -> ULength != n)
  107.             TRIV_FATAL_ERROR(TRIV_ERR_NUM_KNOT_MISMATCH);
  108.  
  109.         RefTV = TrivTVCopy(TV);
  110.         for (i = 0; i < n; i++)
  111.             RefTV -> UKnotVector[i] = *t++;
  112.         break;
  113.         case TRIV_CONST_V_DIR:
  114.         if (TV -> VOrder + TV -> VLength != n)
  115.             TRIV_FATAL_ERROR(TRIV_ERR_NUM_KNOT_MISMATCH);
  116.  
  117.         RefTV = TrivTVCopy(TV);
  118.         for (i = 0; i < n; i++)
  119.             RefTV -> VKnotVector[i] = *t++;
  120.         break;
  121.         case TRIV_CONST_W_DIR:
  122.         if (TV -> WOrder + TV -> WLength != n)
  123.             TRIV_FATAL_ERROR(TRIV_ERR_NUM_KNOT_MISMATCH);
  124.  
  125.         RefTV = TrivTVCopy(TV);
  126.         for (i = 0; i < n; i++)
  127.             RefTV -> WKnotVector[i] = *t++;
  128.         break;
  129.         default:
  130.         TRIV_FATAL_ERROR(TRIV_ERR_DIR_NOT_VALID);
  131.         break;
  132.     }
  133.     }
  134.     else if (n == 0) {
  135.     RefTV = TrivTVCopy(TV);
  136.     }
  137.     else {
  138.     int j, LengthKVt, RULength, RVLength, RWLength;
  139.     BspKnotAlphaCoeffType *A;
  140.     CagdRType *MergedKVt,
  141.         *UKnotVector = TV -> UKnotVector,
  142.         *VKnotVector = TV -> VKnotVector,
  143.         *WKnotVector = TV -> WKnotVector;
  144.  
  145.     switch (Dir) {
  146.         case TRIV_CONST_U_DIR:
  147.         /* Compute the Alpha refinement matrix. */
  148.         MergedKVt = BspKnotMergeTwo(UKnotVector, ULength + UOrder,
  149.                         t, n, 0, &LengthKVt);
  150.         A = BspKnotEvalAlphaCoef(UOrder, UKnotVector, ULength,
  151.                      MergedKVt, LengthKVt - UOrder);
  152.  
  153.             RefTV = TrivBspTVNew(ULength + n, VLength, WLength,
  154.                      UOrder, VOrder, WOrder, TV -> PType);
  155.         IritFree((VoidPtr) RefTV -> UKnotVector);
  156.         IritFree((VoidPtr) RefTV -> VKnotVector);
  157.         IritFree((VoidPtr) RefTV -> WKnotVector);
  158.         RefTV -> UKnotVector = MergedKVt;
  159.         RefTV -> VKnotVector = BspKnotCopy(TV -> VKnotVector,
  160.                     TV -> VLength + TV -> VOrder);
  161.         RefTV -> WKnotVector = BspKnotCopy(TV -> WKnotVector,
  162.                     TV -> WLength + TV -> WOrder);
  163.  
  164.         RULength = RefTV -> ULength;
  165.  
  166.         /* Update the control mesh */
  167.         for (ODim = 0; ODim < VLength * WLength; ODim++) {
  168.             int OIndex = ODim * TRIV_NEXT_V(TV),
  169.             ROIndex = ODim * TRIV_NEXT_V(RefTV);
  170.  
  171.             for (j = IsNotRational; j <= MaxCoord; j++) {
  172.             CagdRType
  173.                 *ROnePts = &RefTV -> Points[j][ROIndex],
  174.                 *OnePts = &TV -> Points[j][OIndex];
  175.  
  176.             for (i = 0;
  177.                  i < RULength;
  178.                  i++, ROnePts += TRIV_NEXT_U(RefTV))
  179.                 CAGD_ALPHA_BLEND_STEP(A, i, OnePts,
  180.                           INFINITY,
  181.                           ROnePts, TRIV_NEXT_U(TV));
  182.             }
  183.         }
  184.  
  185.         BspKnotFreeAlphaCoef(A);
  186.         break;
  187.         case TRIV_CONST_V_DIR:
  188.         /* Compute the Alpha refinement matrix. */
  189.         MergedKVt = BspKnotMergeTwo(VKnotVector, VLength + VOrder,
  190.                         t, n, 0, &LengthKVt);
  191.         A = BspKnotEvalAlphaCoef(VOrder, VKnotVector, VLength,
  192.                      MergedKVt, LengthKVt - VOrder);
  193.  
  194.             RefTV = TrivBspTVNew(ULength, VLength + n, WLength,
  195.                      UOrder, VOrder, WOrder, TV -> PType);
  196.         IritFree((VoidPtr) RefTV -> UKnotVector);
  197.         IritFree((VoidPtr) RefTV -> VKnotVector);
  198.         IritFree((VoidPtr) RefTV -> WKnotVector);
  199.         RefTV -> UKnotVector = BspKnotCopy(TV -> UKnotVector,
  200.                     TV -> ULength + TV -> UOrder);
  201.         RefTV -> VKnotVector = MergedKVt;
  202.         RefTV -> WKnotVector = BspKnotCopy(TV -> WKnotVector,
  203.                     TV -> WLength + TV -> WOrder);
  204.  
  205.         RULength = RefTV -> ULength;
  206.         RVLength = RefTV -> VLength;
  207.  
  208.         /* Update the control mesh */
  209.         for (ODim = 0; ODim < ULength * WLength; ODim++) {
  210.             int OIndex = (ODim / ULength) * TRIV_NEXT_W(TV) +
  211.                  (ODim % ULength) * TRIV_NEXT_U(TV),
  212.                 ROIndex = (ODim / RULength) * TRIV_NEXT_W(RefTV) +
  213.                   (ODim % RULength) * TRIV_NEXT_U(RefTV);
  214.  
  215.             for (j = IsNotRational; j <= MaxCoord; j++) {
  216.             CagdRType
  217.                 *ROnePts = &RefTV -> Points[j][ROIndex],
  218.                 *OnePts = &TV -> Points[j][OIndex];
  219.  
  220.             for (i = 0;
  221.                  i < RVLength;
  222.                  i++, ROnePts += TRIV_NEXT_V(RefTV))
  223.                 CAGD_ALPHA_BLEND_STEP(A, i, OnePts,
  224.                           INFINITY,
  225.                           ROnePts, TRIV_NEXT_V(TV));
  226.             }
  227.         }
  228.  
  229.         BspKnotFreeAlphaCoef(A);
  230.         break;
  231.         case TRIV_CONST_W_DIR:
  232.         /* Compute the Alpha refinement matrix. */
  233.         MergedKVt = BspKnotMergeTwo(WKnotVector, WLength + WOrder,
  234.                         t, n, 0, &LengthKVt);
  235.         A = BspKnotEvalAlphaCoef(WOrder, WKnotVector, WLength,
  236.                      MergedKVt, LengthKVt - WOrder);
  237.  
  238.             RefTV = TrivBspTVNew(ULength, VLength, WLength + n,
  239.                      UOrder, VOrder, WOrder, TV -> PType);
  240.         IritFree((VoidPtr) RefTV -> UKnotVector);
  241.         IritFree((VoidPtr) RefTV -> VKnotVector);
  242.         IritFree((VoidPtr) RefTV -> WKnotVector);
  243.         RefTV -> UKnotVector = BspKnotCopy(TV -> UKnotVector,
  244.                     TV -> ULength + TV -> UOrder);
  245.         RefTV -> VKnotVector = BspKnotCopy(TV -> VKnotVector,
  246.                     TV -> VLength + TV -> VOrder);
  247.         RefTV -> WKnotVector = MergedKVt;
  248.  
  249.         RWLength = RefTV -> WLength;
  250.  
  251.         /* Update the control mesh */
  252.         for (ODim = 0; ODim < ULength * VLength; ODim++) {
  253.             int OIndex = ODim * TRIV_NEXT_U(TV),
  254.             ROIndex = ODim * TRIV_NEXT_U(RefTV);
  255.  
  256.             for (j = IsNotRational; j <= MaxCoord; j++) {
  257.             CagdRType
  258.                 *ROnePts = &RefTV -> Points[j][ROIndex],
  259.                 *OnePts = &TV -> Points[j][OIndex];
  260.  
  261.             for (i = 0;
  262.                  i < RWLength;
  263.                  i++, ROnePts += TRIV_NEXT_W(RefTV))
  264.                 CAGD_ALPHA_BLEND_STEP(A, i, OnePts,
  265.                           INFINITY,
  266.                           ROnePts, TRIV_NEXT_W(TV));
  267.             }
  268.         }
  269.  
  270.         BspKnotFreeAlphaCoef(A);
  271.         break;
  272.         default:
  273.         TRIV_FATAL_ERROR(TRIV_ERR_DIR_NOT_VALID);
  274.         break;
  275.     }
  276.     }
  277.  
  278.     BspKnotMakeRobustKV(RefTV -> UKnotVector,
  279.             RefTV -> UOrder + RefTV -> ULength);
  280.     BspKnotMakeRobustKV(RefTV -> VKnotVector,
  281.             RefTV -> VOrder + RefTV -> VLength);
  282.     BspKnotMakeRobustKV(RefTV -> WKnotVector,
  283.             RefTV -> WOrder + RefTV -> WLength);
  284.  
  285.     return RefTV;
  286. }
  287.